package common.types;

import java.util.HashSet;
import java.util.Set;

import common.enums.DateOfBirthEnum;
import common.enums.HeightEnum;
import common.enums.WeightEnum;

public class FictionalCharacter implements Cloneable {

	private int cid;
	private int mid;
	private String name;
	private Set<String> basedOn;
	private Set<String> placeOfBirth;
	private String gender;
	private Set<String> species;
	private Set<String> parents;
	private Set<String> occupation;
	private Set<String> rank;
	private Set<String> organizations;
	private Set<String> powersOrAbilities;
	private Set<String> appearsInTheseFictinalUniverses;
	private Set<String> children;
	private Set<String> siblings;
	private Set<String> marriedTo;
	private Set<String> characterCreatedBy;
	private Set<String> employers;
	private Set<String> quotations;
	private Set<String> romanticallyInvolvedWith;
	private Set<String> ethnicity;
	private Set<String> education;
	private Set<String> hasPossesed;
	private Set<String> medicalConditions;
	private Set<Pair<DateOfBirthEnum,String>> dateOfBirth;
	private HeightEnum height;
	private WeightEnum weight;
	private Set<String> placesLived;

	public FictionalCharacter(int cid, String name) {
		this.cid = cid;
		this.setName(name);
	}
	
	public FictionalCharacter(int cid, int mid, String name) {
		this(cid,name);
		this.mid = mid;
	}
	
	public FictionalCharacter() {}

	public int getCharacterID() {
		return cid;
	}
	
	public String getName() {
		return name;
	}
	
	public int getMid() {
		return mid;
	}

	public void setMid(int mid) {
		this.mid = mid;
	}

	public Set<String> getBasedOn() {
		if(basedOn == null){
			basedOn = new HashSet<String>();
		}
		return basedOn;
	}

	public Set<String> getPlaceOfBirth() {
		if(placeOfBirth == null){
			placeOfBirth = new HashSet<String>();
		}
		return placeOfBirth;
	}

	public String getGender() {
		return gender;
	}

	public Set<String> getSpecies() {
		if(species == null){
			species = new HashSet<String>();
		}
		return species;
	}

	public Set<String> getParents() {
		if(parents == null){
			parents = new HashSet<String>();
		}
		return parents;
	}

	public Set<String> getOccupation() {
		if(occupation == null){
			occupation = new HashSet<String>();
		}
		return occupation;
	}

	public Set<String> getRank() {
		if(rank == null){
			rank = new HashSet<String>();
		}
		return rank;
	}

	public Set<String> getOrganizations() {
		if(organizations == null){
			organizations = new HashSet<String>();
		}
		return organizations;
	}

	public Set<String> getPowersOrAbilities() {
		if(powersOrAbilities == null){
			powersOrAbilities = new HashSet<String>();
		}
		return powersOrAbilities;
	}

	public Set<String> getAppearsInTheseFictinalUniverses() {
		if(appearsInTheseFictinalUniverses == null){
			appearsInTheseFictinalUniverses = new HashSet<String>();
		}
		return appearsInTheseFictinalUniverses;
	}

	public Set<String> getChildren() {
		if(children == null){
			children = new HashSet<String>();
		}
		return children;
	}

	public Set<String> getSiblings() {
		if(siblings == null){
			siblings = new HashSet<String>();
		}
		return siblings;
	}

	public Set<String> getMarriedTo() {
		if(marriedTo == null){
			marriedTo = new HashSet<String>();
		}
		return marriedTo;
	}

	public Set<String> getCharacterCreatedBy() {
		if(characterCreatedBy == null){
			characterCreatedBy = new HashSet<String>();
		}
		return characterCreatedBy;
	}

	public Set<String> getEmployers() {
		if(employers == null){
			employers = new HashSet<String>();
		}
		return employers;
	}

	public Set<String> getQuotations() {
		if(quotations == null){
			quotations = new HashSet<String>();
		}
		return quotations;
	}

	public Set<String> getRomanticallyInvolvedWith() {
		if(romanticallyInvolvedWith == null){
			romanticallyInvolvedWith = new HashSet<String>();
		}
		return romanticallyInvolvedWith;
	}

	public Set<String> getEthnicity() {
		if(ethnicity == null){
			ethnicity = new HashSet<String>();
		}
		return ethnicity;
	}

	public Set<String> getEducation() {
		if(education == null){
			education = new HashSet<String>();
		}
		return education;
	}

	public Set<String> getHasPossesed() {
		if(hasPossesed == null){
			hasPossesed = new HashSet<String>();
		}
		return hasPossesed;
	}

	public Set<String> getMedicalConditions() {
		if(medicalConditions == null){
			medicalConditions = new HashSet<String>();
		}
		return medicalConditions;
	}

	public Set<Pair<DateOfBirthEnum,String>> getDateOfBirth() {
		if(dateOfBirth == null){
			dateOfBirth = new HashSet<Pair<DateOfBirthEnum,String>>();
		}
		return dateOfBirth;
	}

	public HeightEnum getHeight() {
		if(height == null){
			height = HeightEnum.NULL;
		}
		return height;
	}

	public WeightEnum getWeight() {
		if(weight == null){
			weight = WeightEnum.NULL;
		}
		return weight;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<String> getPlacesLived() {
		if(placesLived == null){
			placesLived = new HashSet<String>();
		}
		return placesLived;
	}

	public void setBasedOn(Set<String> basedOn) {
		this.basedOn = basedOn;
	}

	public void setPlaceOfBirth(Set<String> placeOfBirth) {
		this.placeOfBirth = placeOfBirth;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public void setSpecies(Set<String> species) {
		this.species = species;
	}

	public void setParents(Set<String> parents) {
		this.parents = parents;
	}

	public void setOccupation(Set<String> occupation) {
		this.occupation = occupation;
	}

	public void setRank(Set<String> rank) {
		this.rank = rank;
	}

	public void setOrganizations(Set<String> organizations) {
		this.organizations = organizations;
	}

	public void setPowersOrAbilities(Set<String> powersOrAbilities) {
		this.powersOrAbilities = powersOrAbilities;
	}

	public void setAppearsInTheseFictinalUniverses(
			Set<String> appearsInTheseFictinalUniverses) {
		this.appearsInTheseFictinalUniverses = appearsInTheseFictinalUniverses;
	}

	public void setChildren(Set<String> children) {
		this.children = children;
	}

	public void setSiblings(Set<String> siblings) {
		this.siblings = siblings;
	}

	public void setMarriedTo(Set<String> marriedTo) {
		this.marriedTo = marriedTo;
	}

	public void setCharacterCreatedBy(Set<String> characterCreatedBy) {
		this.characterCreatedBy = characterCreatedBy;
	}

	public void setEmployers(Set<String> employers) {
		this.employers = employers;
	}

	public void setQuotations(Set<String> quotations) {
		this.quotations = quotations;
	}

	public void setRomanticallyInvolvedWith(Set<String> romanticallyInvolvedWith) {
		this.romanticallyInvolvedWith = romanticallyInvolvedWith;
	}

	public void setEthnicity(Set<String> ethnicity) {
		this.ethnicity = ethnicity;
	}

	public void setEducation(Set<String> education) {
		this.education = education;
	}

	public void setHasPossesed(Set<String> hasPossesed) {
		this.hasPossesed = hasPossesed;
	}

	public void setMedicalConditions(Set<String> medicalConditions) {
		this.medicalConditions = medicalConditions;
	}

	public void setDateOfBirth(Set<Pair<DateOfBirthEnum,String>> dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public void setHeight(HeightEnum height) {
		this.height = height;
	}

	public void setWeight(WeightEnum weight) {
		this.weight = weight;
	}

	public void setPlacesLived(Set<String> placesLived) {
		this.placesLived = placesLived;
	}
	
	@Override
	public String toString() {
		return getName();
	}

	@Override
	public boolean equals(Object obj) {
		return cid == ((FictionalCharacter)obj).getCharacterID();
	}
	
	public Set<String> get(String charRelationName){

		if(charRelationName.equalsIgnoreCase("CharacterBasedOn")){return getBasedOn();}
		if(charRelationName.equalsIgnoreCase("CharacterPlaceOfBirth")){return getPlaceOfBirth();}
		if(charRelationName.equalsIgnoreCase("CharacterSpecies")){return getSpecies();}
		if(charRelationName.equalsIgnoreCase("CharacterParent")){return getParents();}
		if(charRelationName.equalsIgnoreCase("CharacterOccupation")){return getOccupation();}
		if(charRelationName.equalsIgnoreCase("CharacterRank")){return getRank();}
		if(charRelationName.equalsIgnoreCase("CharacterOrganization")){return getOrganizations();}
		if(charRelationName.equalsIgnoreCase("CharacterPowers")){return getPowersOrAbilities();}
		if(charRelationName.equalsIgnoreCase("CharacterUniverses")){return getAppearsInTheseFictinalUniverses();}
		if(charRelationName.equalsIgnoreCase("CharacterChildren")){return getChildren();}
		if(charRelationName.equalsIgnoreCase("CharacterSibling")){return getSiblings();}
		if(charRelationName.equalsIgnoreCase("CharacterMarriedTo")){return getMarriedTo();}
		if(charRelationName.equalsIgnoreCase("CharacterCreatedBy")){return getCharacterCreatedBy();}
		if(charRelationName.equalsIgnoreCase("CharacterEmployer")){return getEmployers();}
		if(charRelationName.equalsIgnoreCase("CharacterQuotation")){return getQuotations();}
		if(charRelationName.equalsIgnoreCase("CharacterRomanticallyInvolvedWith")){return getRomanticallyInvolvedWith();}
		if(charRelationName.equalsIgnoreCase("CharacterEthnicity")){return getEthnicity();}
		if(charRelationName.equalsIgnoreCase("CharacterSchool")){return getEducation();}
		if(charRelationName.equalsIgnoreCase("CharacterPossesedObject")){return getHasPossesed();}
		if(charRelationName.equalsIgnoreCase("CharacterMedicalCondition")){return getMedicalConditions();}
		if(charRelationName.equalsIgnoreCase("CharacterPlacesLived")){return getPlacesLived();}
		
		return null;
	}	
	
	public void set(String charRelationName, Set<String> setToSet){

		if(charRelationName.equalsIgnoreCase("CharacterBasedOn")){setBasedOn(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterPlaceOfBirth")){setPlaceOfBirth(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterSpecies")){setSpecies(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterParent")){setParents(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterOccupation")){setOccupation(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterRank")){setRank(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterOrganization")){setOrganizations(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterPowers")){setPowersOrAbilities(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterUniverses")){setAppearsInTheseFictinalUniverses(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterChildren")){setChildren(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterSibling")){setSiblings(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterMarriedTo")){setMarriedTo(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterCreatedBy")){setCharacterCreatedBy(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterEmployer")){setEmployers(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterQuotation")){setQuotations(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterRomanticallyInvolvedWith")){setRomanticallyInvolvedWith(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterEthnicity")){setEthnicity(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterSchool")){setEducation(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterPossesedObject")){setHasPossesed(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterMedicalCondition")){setMedicalConditions(setToSet); return;}
		if(charRelationName.equalsIgnoreCase("CharacterPlacesLived")){setPlacesLived(setToSet); return;}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Object clone() throws CloneNotSupportedException {
		FictionalCharacter clone = (FictionalCharacter) super.clone();
		clone.cid = cid;
		clone.mid = mid;
		clone.name = name;
		clone.gender = gender;
		clone.height = height;
		clone.weight = weight;
		clone.basedOn = basedOn == null ? null : new HashSet<String>(basedOn);
		clone.placeOfBirth = placeOfBirth == null ? null : new HashSet<String>(placeOfBirth);
		clone.species = species == null ? null : new HashSet<String>(species);
		clone.parents = parents == null ? null : new HashSet<String>(parents);
		clone.occupation = occupation == null ? null : new HashSet<String>(occupation);
		clone.rank = rank == null ? null : new HashSet<String>(rank);
		clone.organizations = organizations == null ? null : new HashSet<String>(organizations);
		clone.powersOrAbilities = powersOrAbilities == null ? null : new HashSet<String>(powersOrAbilities);
		clone.appearsInTheseFictinalUniverses = appearsInTheseFictinalUniverses == null ? null : new HashSet<String>(appearsInTheseFictinalUniverses);
		clone.children = children == null ? null : new HashSet<String>(children);
		clone.siblings = siblings == null ? null : new HashSet<String>(siblings);
		clone.marriedTo = marriedTo == null ? null : new HashSet<String>(marriedTo);
		clone.characterCreatedBy = characterCreatedBy == null ? null : new HashSet<String>(characterCreatedBy);
		clone.employers = employers == null ? null : new HashSet<String>(employers);
		clone.quotations = quotations == null ? null : new HashSet<String>(quotations);
		clone.romanticallyInvolvedWith = romanticallyInvolvedWith == null ? null : new HashSet<String>(romanticallyInvolvedWith);
		clone.ethnicity = ethnicity == null ? null : new HashSet<String>(ethnicity);
		clone.education = education == null ? null : new HashSet<String>(education);
		clone.hasPossesed = hasPossesed == null ? null : new HashSet<String>(hasPossesed);
		clone.medicalConditions = medicalConditions == null ? null : new HashSet<String>(medicalConditions);
		clone.placesLived = placesLived == null ? null : new HashSet<String>(placesLived);
		Set<Pair<DateOfBirthEnum,String>> set = null;
		if (dateOfBirth != null) {
			set = new HashSet<Pair<DateOfBirthEnum,String>>();
			for (Pair<DateOfBirthEnum, String> pair : dateOfBirth) {
				set.add((Pair<DateOfBirthEnum, String>) pair.clone());
			}
		}
		clone.dateOfBirth = set;
		return clone;
	}

}
